package controllers

import (
	"net/http"
	"obsidian-plugin-server/config"
	"obsidian-plugin-server/middleware"
	"obsidian-plugin-server/models"
	"obsidian-plugin-server/utils"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"gorm.io/gorm"
)

type TokenController struct {
	DB        *gorm.DB
	JWTConfig *config.JWTConfig
}

// RotateToken 轮换 API Token
func (tc *TokenController) RotateToken(c *gin.Context) {
	user := middleware.GetUserFromContext(c)
	if user == nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"error":   "Unauthorized",
			"message": "User not found",
		})
		return
	}

	// 获取当前 token
	authHeader := c.GetHeader("Authorization")
	if authHeader == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Token 轮换失败,请检查当前 Token 是否有效",
		})
		return
	}

	tokenString := strings.TrimPrefix(authHeader, "Bearer ")

	// 验证当前 token
	token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		return []byte(tc.JWTConfig.Secret), nil
	})

	if err != nil || !token.Valid {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"message": "Token 轮换失败,请检查当前 Token 是否有效",
		})
		return
	}

	// 记录旧 token 信息
	oldTokenHash := tokenString[:16]

	// 生成新 token
	newToken, err := utils.GenerateApiToken(user, tc.JWTConfig)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "生成新 Token 失败: " + err.Error(),
		})
		return
	}

	// 记录 token 轮换日志
	notes := "旧 Token: " + oldTokenHash + "..."
	tokenLog := models.Log(user.ID, "rotated", newToken[:16], c.ClientIP(), c.Request.UserAgent(), &notes)
	tc.DB.Create(tokenLog)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "API Token 已成功更换,旧 Token 已失效",
		"data": gin.H{
			"token": newToken,
		},
	})
}
